<!-- HTML header for doxygen 1.8.5-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.17"/>
<title>GenAVB/TSN: Linux platform specific</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script src="http://www.freescale.com/files/abstract/misc/COLLATERALTEMPLATE_infocenter.js" type="text/javascript" xml:space="preserve"><!-- --></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
  $(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="html_custom.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="nxp_logo.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">GenAVB/TSN
   </div>
  </td>
   <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
</td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.17 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('platform_linux.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="PageDoc"><div class="header">
  <div class="headertitle">
<div class="title">Linux platform specific </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="autotoc_md130"></a>
Media clock driver</h1>
<p>The media clock driver provides media clock generation and recovery mechanisms for the AVB stack. Media clock generation generates timestamps and wake-up events whereas the media clock recovery consumes timestamps to synchronize an audio clock.</p>
<p>The media clock driver supports various HW devices which are registered via Linux device tree.</p>
<h2><a class="anchor" id="autotoc_md131"></a>
DMA based recovery and generation</h2>
<p>Available on i.MX6 family platforms, it requires an external multiplier for recovery and a divider for the generation.</p>
<p>Recovery: The SDMA is used to copy timestamps from memory to ENET Timer Compare Output. This generates a low-frequency clock (around 300-6000Hz) used as an input for a multiplier device and looped-back to SDMA external event.</p>
<p>Generation: The audio clock is divided to get a low-frequency clock which drives both ENET Timer Input Capture and SDMA to capture and copy timestamps to memory.</p>
<p>The device tree node can register a DMA recovery and/or a DMA generation mechanism.</p>
<h3><a class="anchor" id="autotoc_md132"></a>
AVB DMA node</h3>
<p>Required properties:</p><ul>
<li>compatible: should be "fsl,imx6q-avb".</li>
<li>domain: domain ID.</li>
<li>dmas: List of one or 2 SDMA properties in DMA client format.</li>
<li>dma-names: List of one or 2 dma names. Can be either "rec" for recovery or "gen" for generation.</li>
<li>tc_reg_id: List of one or 2 FEC ENET Timer Compare ID used in the DMA mechanism. It is the TCCR/TCSR register ID (0-3)</li>
<li>enet: reference to the FEC ENET node.</li>
<li>multiplier: reference to a multiplier device. (Only CS2000 is supported). Required for recovery.</li>
<li>divider: reference to a divider device. (Only MLE145170 is supported). Required for generation.</li>
</ul>
<p>Example: </p><pre class="fragment">avb {
    compatible = "fsl,imx6q-avb";
    pinctrl-names = "default";
    pinctrl-0 = &lt;&amp;pinctrl_avb&gt;;
    domain = &lt;0&gt;;
    dmas = &lt;&amp;sdma 14 26 0&gt;;
    tc_reg_id = &lt;0&gt;;
    dma-names = "rec";
    enet = &lt;&amp;fec&gt;;
    multiplier = &lt;&amp;cs2000&gt;;
    status = "okay";
};
</pre><h3><a class="anchor" id="autotoc_md133"></a>
CS2000 node</h3>
<p>I2C client, multiplier device that can be referenced by the AVB DMA node.</p>
<p>Required properties:</p><ul>
<li>compatible: should be "cirrus,cs2000".</li>
<li>reg: should be &lt;0x4e&gt;.</li>
<li>clocks: references for "ref_clk" and "clk_out".</li>
<li>clocks-names: should be "ref_clk", "clk_out". "ref_clk" is the reference clock of CS2000, it needs to be a stable low-jitter clock (e.g. crystal oscillator). "clk_out" is the audio clock "desired" frequency.</li>
</ul>
<p>Example: </p><pre class="fragment">cs2000: cs2000@4e {
    compatible = "cirrus,cs2000";
    reg = &lt;0x4e&gt;;
    clocks = &lt;&amp;codec_osc&gt;, &lt;&amp;codec_osc&gt;;
    clock-names = "ref_clk", "clk_out";
};
</pre><h3><a class="anchor" id="autotoc_md134"></a>
MLE14570</h3>
<p>SPI client, divider device that can be referenced by the AVB DMA node.</p>
<p>Required properties:</p><ul>
<li>compatible: should be "lansdale,mle145170".</li>
<li>reg: should be &lt;0&gt;.</li>
<li>clocks: reference for "clk_in".</li>
<li>clocks-names: should be "clk_in".</li>
</ul>
<p>Example: </p><pre class="fragment">mle145170: spi@0 {
    compatible = "lansdale,mle145170";
    reg = &lt;0&gt;;
    spi-max-frequency = &lt;3000000&gt;;
    clocks = &lt;&amp;codec_osc&gt;;
    clock-names = "clk_in";
};
</pre><h2><a class="anchor" id="autotoc_md135"></a>
Internal audio PLL recovery</h2>
<p>Available on imx6 soloX. On this platform, the audio PLL has the capability to be tuned on-the-fly which provides a more integrated solution that doesn't require additional external devices. The audio clock needs to be generated by the SoC and measured using gPTP based events.</p>
<p>Current implementation uses the GPT block to measure the audio clock. The capture is triggered by timestamps coming from the remote stream and therefore provides measurements in the remote clock domain. These measurements are fed to a PID loop used to tune the audio PLL.</p>
<h3><a class="anchor" id="autotoc_md136"></a>
AVB internal recovery node</h3>
<p>Required properties:</p><ul>
<li>compatible: should be "fsl,avb-gpt".</li>
<li>domain: domain ID.</li>
<li>rec-channel: array of 3 elements. GPT capture channel (capture channel 1 or 2), ethernet port and ENET Timer Compare ID.</li>
<li>prescale: pre-divider of GPT Timer IP.</li>
<li>clocks: references to "ipg" , "per" , "audio_pll" and optionally "clk_in" clocks.</li>
<li>clock-names: should be "ipg", "per", "audio_pll and "clk_in".
    - "ipg" is the GPT clock gate
    - "per" is the peripheral clock : in case of internal routing of the gpt root clock to be derived from the audio pll, this clock will be the counter clock and no need for the (external) clk_in clock<ul>
<li>"clk_in" is the clock connected to the GPT in case of no internal routing is possible and external clock is needed to feed the gpt clock from the audio pll</li>
<li>"audio_pll": The Audio PLL to be tuned external clock input.</li>
</ul>
</li>
</ul>
<p>Example with an external clk source: </p><pre class="fragment">&amp;gpt {
    compatible = "fsl,avb-gpt";
    pinctrl-names = "default";
    pinctrl-0 = &lt;&amp;pinctrl_avb&gt;;
    domain = &lt;0&gt;;
    rec-channel = &lt;1 0 1&gt;; // capture channel, eth port, ENET TC id
    prescale = &lt;1&gt;;
    clocks = &lt;&amp;clks IMX6SX_CLK_GPT_BUS&gt;, &lt;&amp;clks &gt;IMX6SX_CLK_GPT_BUS;
        &lt;&amp;clks IMX6SX_CLK_AUDIO&gt;, &lt;&amp;clks IMX6SX_CLK_PLL4&gt;;
    clock-names = "ipg", "per", "clk_in", "audio_pll";
    status = "okay";
};
</pre><p>Example with the gpt root clock derived from the audio pll internally: </p><pre class="fragment">&amp;gpt1 {
    compatible = "fsl,avb-gpt";
    pinctrl-names = "default";
    pinctrl-0 = &lt;&amp;pinctrl_avb&gt;;
    domain = &lt;0&gt;;
    rec-channel = &lt;1 0 1&gt;; // capture channel, eth port, ENET TC id
    prescale = &lt;1&gt;;

    clocks = &lt;&amp;clk IMX8MQ_CLK_GPT1_ROOT&gt;,
     &lt;&amp;clk IMX8MQ_CLK_GPT1_ROOT&gt;,
     &lt;&amp;clk IMX8MQ_AUDIO_PLL1&gt;;
    clock-names = "ipg", "per", "audio_pll";

    /* Make the GPT clk root derive from the audio PLL*/
    assigned-clocks = &lt;&amp;clk IMX8MQ_CLK_GPT1_SRC&gt;,
            &lt;&amp;clk IMX8MQ_CLK_GPT1_DIV&gt;;
    assigned-clock-parents = &lt;&amp;clk IMX8MQ_AUDIO_PLL1_OUT&gt;;
    assigned-clock-rates = &lt;0&gt;, &lt;12288000&gt;;

    status = "okay";
};
</pre><h3><a class="anchor" id="autotoc_md137"></a>
AVB HW timer node</h3>
<p>Required properties:</p><ul>
<li>compatible: should be "fsl,avb-gpt".</li>
<li>timer-channel: GPT output compare channel (output channel 1, 2 or 3)</li>
<li>prescale: pre-divider of GPT Timer IP.</li>
<li>clocks: references to "ipg" and "per" clocks.</li>
<li>clock-names: should be "ipg" and "per". "ipg" is the GPT clock gate, "per" is the peripheral clock used as counter clock</li>
</ul>
<p>Example: </p><pre class="fragment">&amp;gpt {
    compatible = "fsl,avb-gpt";
    timer-channel = &lt;1&gt;;
    prescale = &lt;1&gt;;
    clocks = &lt;&amp;clks IMX6SX_CLK_GPT_BUS&gt;, &lt;&amp;clks IMX6SX_CLK_GPT_BUS&gt;;
    clock-names = "ipg", "per";
    status = "okay";
};
</pre><p>The GPT driver supports both functioning modes : Internal recovery and HW timer. Thus, specifying both properties "rec-channel" and "timer-channel" in the AVB specific GPT node will enable both modes. </p>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<!-- HTML footer for doxygen 1.8.5-->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul class="foot">
    <li class="footer"> &copy; 2017-2020 NXP
    </li>
  </ul>
</div>
</body>
</html>
